package com.dc.juc.example._10_aqs;

import com.google.common.base.Throwables;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * Description: Semaphore 信号量
 *  可以用来控制同时访问特定资源的线程数量，通过协调各个线程，以保证合理的使用资源。
 *
 *      执行的现象：threadNum 会 1s 打印3个
 *
 * @author: gdc
 * @date: 2021/8/13
 * @version 1.0
 */
@Slf4j
public class Semaphore1 {

    private static final int THREAD_COUNT = 20;

    @SneakyThrows
    public static void main(String[] args){
        ExecutorService threadPool = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < THREAD_COUNT; i++) {
            threadPool.execute(() -> {
                try {
                    semaphore.acquire();                // 获取一个许可

                    test(Thread.currentThread().getId());

                    semaphore.release();                // 释放一个许可
                } catch (Exception e){
                    log.error("异常信息为：{}", Throwables.getStackTraceAsString(e));
                }
            });
        }

        // 关闭线程池，调用shutdown()后，会在已经启动的线程执行完之后关闭
        threadPool.shutdown();
    }


    @SneakyThrows
    private static void test(long threadNum) {
        TimeUnit.MILLISECONDS.sleep(1000);
        log.info("{}", threadNum);
    }

}
